package service4gateway

import (
	UserAction "MyBlogv2/Servers/UserAction/userAction"
	"MyBlogv2/blog-common/HttpCode"
	"MyBlogv2/blog-common/helper"
	"MyBlogv2/blog-common/models"
	"MyBlogv2/blog-common/response"
	"github.com/gin-gonic/gin"
	"github.com/jinzhu/copier"
	"io"
	"strconv"
	"time"
)

func Register(c *gin.Context) {
	var user UserAction.UserRegisterDto
	if err := c.ShouldBindJSON(&user); err != nil {
		response.ResponseError(c, HttpCode.PARAM_ERROR)
	}
	user.RegisterIp = c.ClientIP()
	rsp, _ := clientOfUserAction.Register(c.Request.Context(), &user)
	response.CommonResponse(c, HttpCode.AppHttpCodeEnum(rsp.Code), rsp.Data, rsp.Msg)
	return
}

func Login(c *gin.Context) {
	username := c.PostForm("username")
	password := c.PostForm("password")
	loginIp := c.ClientIP()
	rsp, _ := clientOfUserAction.Login(c.Request.Context(), &UserAction.LoginRequest{
		Username: username,
		Password: password,
		LoginIp:  loginIp,
	})
	if rsp.Code != 200 {
		response.ResponseError(c, HttpCode.AppHttpCodeEnum(rsp.Code))
	} else {
		response.ResponseOK(c, gin.H{
			"token":  rsp.Token,
			"expire": time.Hour * 24 * 30,
		})
	}
	return
}

func GetUserInfo(c *gin.Context) {
	userId, _ := c.Get("userId")
	rsp, _ := clientOfUserAction.GetUserInfo(c.Request.Context(), &UserAction.UserActionRequest{
		UserId: int64(userId.(int)),
	})
	var userInfoVo models.UserAccountVo
	copier.Copy(&userInfoVo, rsp.Data)
	userInfoVo.CreateTime = helper.TimestampToMyTime(rsp.Data.CreateTime)
	userInfoVo.LoginTime = helper.TimestampToMyTime(rsp.Data.LoginTime)
	response.CommonResponse(c, HttpCode.AppHttpCodeEnum(rsp.Code), userInfoVo, rsp.Msg)

}

func UpdateAvatar(c *gin.Context) {
	userId, _ := c.Get("userId")
	file, _ := c.FormFile("avatarFile")
	filename := file.Filename
	filePath, err := file.Open()
	if err != nil {
		response.ResponseError(c, HttpCode.FILE_UPLOAD_ERROR)
		return
	}
	avatar, _ := io.ReadAll(filePath)
	rsp, _ := clientOfUserAction.UpdateAvatar(c.Request.Context(), &UserAction.UpdateAvatarRequest{
		UserId:   int64(userId.(int)),
		Avatar:   avatar,
		Filename: filename,
	})
	response.CommonResponse(c, HttpCode.AppHttpCodeEnum(rsp.Code), rsp.Data, rsp.Msg)

}

func Logout(c *gin.Context) {
	response.ResponseOK(c, nil)
}

func UpdateUserInfo(c *gin.Context) {
	userId, _ := c.Get("userId")
	var userUpdateDto UserAction.UserUpdateDto
	if err := c.ShouldBindJSON(&userUpdateDto); err != nil {
		response.ResponseError(c, HttpCode.PARAM_ERROR)
		return
	}
	rsp, _ := clientOfUserAction.UpdateUserInfo(c.Request.Context(), &UserAction.UpdateUserInfoRequest{
		UserUpdateDto: &userUpdateDto,
		UserId:        int64(userId.(int)),
	})
	response.CommonResponse(c, HttpCode.AppHttpCodeEnum(rsp.Code), rsp.Data, rsp.Msg)
	return
}

func GetUserList(c *gin.Context) {
	var userList []models.UserListVo
	models.Db.Model(new(models.UserListVo)).Find(&userList)
	response.ResponseOK(c, userList)
	return

}
func SearchUserList(c *gin.Context) {
	var userList []models.UserListVo
	var userSearchDto models.UserSearchDto
	if err := c.ShouldBindJSON(&userSearchDto); err != nil {
		response.ResponseError(c, HttpCode.PARAM_ERROR)
	}
	db := models.Db.Model(new(models.UserListVo))
	if userSearchDto.Username != "" {
		db.Where("username like ?", "%"+userSearchDto.Username+"%")
	}
	if userSearchDto.Email != "" {
		db.Where("email like ?", "%"+userSearchDto.Email+"%")
	}
	if userSearchDto.IsDisable.Valid {
		db.Where("is_disable = ?", userSearchDto.IsDisable.Int64)
	}
	if !time.Time(userSearchDto.CreateTimeStart).IsZero() {
		db.Where("created_at >= ?", userSearchDto.CreateTimeStart)
	}
	if !time.Time(userSearchDto.CreateTimeEnd).IsZero() {
		db.Where("created_at <= ?", userSearchDto.CreateTimeEnd)
	}
	db.Find(&userList)
	response.ResponseOK(c, userList)
	return

}

func FindUserDetailById(c *gin.Context) {
	id, _ := strconv.Atoi(c.Param("id"))
	var user models.UserDetailsVo
	models.Db.Model(new(models.UserDetailsVo)).Where("id = ?", id).Find(&user)
	var roles []string
	models.Db.Model(new(models.UserRole)).
		Table("sys_user_role ur").
		Select("r.role_key").
		Joins("left join sys_role r on ur.role_id = r.id").
		Where("ur.user_id = ?", id).Find(&roles)
	user.Roles = roles
	response.ResponseOK(c, user)
	return

}

func UpdateUserStatus(c *gin.Context) {
	var updateUserStatusDto models.UpdateUserStatusDto
	if err := c.ShouldBindJSON(&updateUserStatusDto); err != nil {
		response.ResponseError(c, HttpCode.PARAM_ERROR)
		return
	}
	models.Db.Model(new(models.User)).Where("id = ?", updateUserStatusDto.Id).Update("is_disable", updateUserStatusDto.Status)
	response.ResponseOK(c, nil)
	return

}

func DeleteUserByIds(c *gin.Context) {
	var userDeleteDto models.UserDeleteDto
	if err := c.ShouldBindJSON(&userDeleteDto); err != nil {
		response.ResponseError(c, HttpCode.PARAM_ERROR)
		return
	}
	models.Db.Model(new(models.User)).Where("id in (?)", userDeleteDto.Ids).Delete(new(models.User))
	models.Db.Model(new(models.UserRole)).Where("user_id in (?)", userDeleteDto.Ids).Delete(new(models.UserRole))
	models.Db.Model(new(models.Comment)).Where("user_id in (?)", userDeleteDto.Ids).Delete(new(models.Comment))
	models.Db.Model(new(models.Like)).Where("user_id in (?)", userDeleteDto.Ids).Delete(new(models.Like))
	models.Db.Model(new(models.Favorite)).Where("user_id in (?)", userDeleteDto.Ids).Delete(new(models.Favorite))
	models.Db.Model(new(models.Article)).Where("user_id in (?)", userDeleteDto.Ids).Delete(new(models.Article))
	models.Db.Model(new(models.LeaveWord)).Where("user_id in (?)", userDeleteDto.Ids).Delete(new(models.LeaveWord))
	models.Db.Model(new(models.TreeHole)).Where("user_id in (?)", userDeleteDto.Ids).Delete(new(models.TreeHole))
	//TODO友链
	response.ResponseOK(c, nil)
	return
}
